package com.wang.immutable;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Map
 * @author yandong
 */
public class ImmutableDemo3 {
    public static void main(String[] args) {
        /*
         * 创建不可变的Map集合
         * {"张三", "李四", "王五", "赵六"}
         * 注: Map的of方法, 参数是有上限的, 最多只能传递20个参数(即10个键值对).
         */
        Map<String, String> map = Map.of("张三", "南京", "李四", "北京",
                "王五", "上海", "赵六", "广州",
                "孙七", "深圳", "周八", "杭州",
                "吴九", "宁波", "郑十", "苏州",
                "刘一", "无锡", "陈二", "嘉兴");

        Set<String> keys = map.keySet();
        for (String key : keys) {
            String value = map.get(key);
            System.out.println(key + ": " + value);
        }
        System.out.println("===========================");

        Set<Map.Entry<String, String>> entries = map.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + ": " + value);
        }
        System.out.println("=========================== ===========================");


        /*
         * 创建能传递10个以上键值对的 不可变Map集合
         */
        HashMap<String, String> hm = new HashMap<>();
        // 添加11个键值对
        hm.put("张三", "南京");
        hm.put("李四", "北京");
        hm.put("王五", "上海");
        hm.put("赵六", "广州");
        hm.put("孙七", "深圳");
        hm.put("周八", "杭州");
        hm.put("吴九", "宁波");
        hm.put("郑十", "苏州");
        hm.put("刘一", "无锡");
        hm.put("陈二", "嘉兴");
        hm.put("钱十一", "天津");

        // 1.获取所有键值对的Set集合 (每个元素是Entry类型的键值对对象)
        Set<Map.Entry<String, String>> entries1 = hm.entrySet();

        // 2.创建一个长度为0的Map.Entry数组 (作为toArray()方法的参数, 指定返回数组的类型)
        Map.Entry[] arr1 = new Map.Entry[0];

        // 3.将entries1集合中的所有键值对转换为Map.Entry数组并赋值给arr2
        // 注:
        // - 集合长度 > 数组arr1的长度 --> 根据实际数据的个数,重新创建一个与集合元素数量匹配的新数组
        // - 集合长度 <= 数组arr1的长度 --> 直接使用数组arr1
        Map.Entry[] arr2 = entries1.toArray(arr1);

        // 4.通过Map.ofEntries()方法将arr2数组中的键值对转换为一个不可变Map
        Map<String, String> map1 = Map.ofEntries(arr2);
        System.out.println(map1);

        // 尝试向不可变map中添加元素 (会报错)
        // map1.put("诸葛", "南阳");


        // 简化上述代码:
        Map<Object, Object> map2 = Map.ofEntries(hm.entrySet().toArray(new Map.Entry[0]));
        System.out.println(map2);
        // 尝试向不可变map中添加元素 (会报错)
        // map2.put("诸葛", "南阳");

        // 继续简化: 使用Map.copyOf()方法
        // 注: copyOf()方法在jdk10中才引入, 使用时要注意一下JDK版本
        Map<Object, Object> map3 = Map.copyOf(hm);
        System.out.println(map3);
    }
}
